package orders

import (
	"github.com/jinzhu/gorm"
	"time"
)

//CREATE TABLE `orders` (
//`id` int NOT NULL AUTO_INCREMENT,
//`order_id` varchar(64) NOT NULL COMMENT '订单号(业务唯一)',
//`order_type` tinyint unsigned NOT NULL DEFAULT '1' COMMENT '订单类型',
//`trans_type` tinyint NOT NULL DEFAULT '1' COMMENT '交易类型 1充值 2支出',
//`user_id` bigint NOT NULL COMMENT '用户ID',
//`amount` decimal(15,2) NOT NULL COMMENT '金额',
//`actual_amount` decimal(15,2) DEFAULT NULL COMMENT '实际支付金额(可能有优惠)',
//`payment_source` varchar(20) NOT NULL COMMENT '支付方式',
//`status` tinyint NOT NULL DEFAULT '0' COMMENT '状态(0-待支付,1-支付成功,2-支付失败,3-已取消)',
//`transaction_id` varchar(128) DEFAULT NULL COMMENT '第三方支付交易号',
//`pay_time` datetime DEFAULT NULL COMMENT '支付时间',
//`callback_time` datetime DEFAULT NULL COMMENT '回调时间',
//`callback_content` text COMMENT '回调内容',
//`client_ip` varchar(50) DEFAULT NULL COMMENT '客户端IP',
//`device_info` varchar(255) DEFAULT NULL COMMENT '设备信息',
//`remark` varchar(255) DEFAULT NULL COMMENT '备注',
//`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
//`updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
// `product_id` int DEFAULT NULL COMMENT '商品Id',
//  `package_id` int DEFAULT NULL COMMENT '商品套餐Id',
//`quantity` int DEFAULT NULL,
//PRIMARY KEY (`id`),
//KEY `idx_order_id` (`order_id`),
//KEY `idx_user_id` (`user_id`),
//KEY `idx_status` (`status`),
//KEY `idx_created_at` (`created_at`)
//) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='订单表';

type Orders struct {
	Id              int64     `json:"id" gorm:"primary_key;column:id"`
	TradeNo         string    `json:"trade_no" gorm:"column:trade_no"`
	UserId          string    `json:"user_id" gorm:"column:user_id"`
	Amount          float64   `json:"amount" gorm:"column:amount"`
	ActualAmount    float64   `json:"actual_amount" gorm:"column:actual_amount"`
	PaymentSource   string    `json:"payment_source" gorm:"column:payment_source"`
	Status          int       `json:"status" gorm:"column:status"`
	TransType       int       `json:"trans_type" gorm:"column:trans_type"`
	TransactionId   string    `json:"transaction_id" gorm:"column:transaction_id"`
	PayTime         time.Time `json:"pay_time" gorm:"column:pay_time"`
	ClientIp        string    `json:"client_ip" gorm:"column:client_ip"`
	DeviceInfo      string    `json:"device_info" gorm:"column:device_info"`
	Remark          string    `json:"remark" gorm:"column:remark"`
	CreatedAt       time.Time `json:"created_at" gorm:"column:created_at"`
	UpdatedAt       time.Time `json:"updated_at" gorm:"column:updated_at"`
	CallbackTime    time.Time `json:"callback_time" gorm:"column:callback_time"`
	CallbackContent string    `json:"callback_content" gorm:"column:callback_content"`
	OrderType       int       `json:"order_type" gorm:"column:order_type"`
	ProductId       int       `json:"product_id" gorm:"column:product_id"`
	PackageId       int       `json:"package_id" gorm:"column:package_id"`
	Quantity        int       `json:"quantity" gorm:"column:quantity"`
}
type TransType int

const (
	TransType_Recharge TransType = iota + 1
	TransType_Withdraw
)

type OrderStatus int

const (
	OrderStatus_Pending OrderStatus = iota
	OrderStatus_Success
	OrderStatus_Failed
	OrderStatus_Cancel
)

type OrderType int

const (
	OrderTypeRecharge OrderType = 1
	OrderTypeInstance OrderType = 2
	OrderTypeRenew    OrderType = 3
)

func (a *Orders) TableName() string {
	return "orders"
}
func (a *Orders) Create(db *gorm.DB) error {
	return db.Table(a.TableName()).Create(a).Error
}
func (a *Orders) Update(db *gorm.DB) error {
	return db.Table(a.TableName()).Where("id = ?", a.Id).Updates(a).Error
}
func (a *Orders) GetById(db *gorm.DB) error {
	return db.Table(a.TableName()).Where("id = ?", a.Id).First(a).Error
}

func (a *Orders) GetByIdForUpdate(db *gorm.DB) error {

	return db.Table(a.TableName()).Set("gorm:query_option", "FOR UPDATE").Where("id = ?", a.Id).First(a).Error
}

func (o *Orders) FindByTradeNo(db *gorm.DB) error {
	return db.Table(o.TableName()).Where("trade_no = ?", o.TradeNo).First(o).Error
}

func (o *Orders) GetList(db *gorm.DB, userId string, offset int, limit int, search map[string]interface{}) ([]Orders, int, error) {
	var orderList []Orders
	obj := db.Table(o.TableName()).Where("user_id = ?", userId)
	if status, ok := search["status"]; ok {
		obj.Where("status = ?", status)
	}
	if transType, ok := search["transType"]; ok {
		obj.Where("trans_type = ?", transType)
	}
	if orderType, ok := search["orderType"]; ok {
		obj.Where("order_type = ?", orderType)
	}
	if start, ok := search["startTime"]; ok {
		obj.Where("created_at >= ?", start)
	}
	if end, ok := search["endTime"]; ok {
		obj.Where("created_at <= ?", end)
	}
	count := 0
	obj.Count(&count)
	err := obj.Offset(offset).Limit(limit).Order("id desc").Find(&orderList).Error
	return orderList, count, err
}
func (o *Orders) GetListPendingAndExpire(db *gorm.DB) ([]Orders, error) {
	var orderList []Orders

	return orderList, db.Table(o.TableName()).Where("status = ?", OrderStatus_Pending).Where("created_at <= ?", time.Now().Add(-time.Minute*5)).Find(&orderList).Error
}

func (o *Orders) CountPurchesedForUsedCoupon(db *gorm.DB, userId string) (int, error) {
	var count int
	return count, db.Table(o.TableName()).Where("user_id = ?", userId).Where("status = ?", OrderStatus_Success).Where("order_type = ?", OrderTypeInstance).Count(&count).Error
}

//	func (a *Orders) GetListByUserId(db *gorm.DB) (applications []Orders, err error) {
//		return applications, db.Table(a.TableName()).Preload("Role").Where("user_id = ?", a.UserId).Where("status = ?", 1).Find(&applications).Error
//	}
func (a *Orders) GetOrderByStatusAndUserIdAndCatId(db *gorm.DB, status int, userId string, catId int) (order Orders, err error) {
	return order, db.Table(a.TableName()).Joins("join instance_uses on instance_uses.order_id = orders.id").Joins("join instances on instances.id = instance_uses.instance_id").Where("orders.status = ?", status).Where("orders.user_id = ?", userId).Where("instances.cat_id = ?", catId).First(&order).Error
}
